home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#49 (Oct 89)
/
DMP Source
/
src
/
pdef4.c
< prev
next >
Wrap
Text File
|
1989-01-02
|
14KB
|
504 lines
/*
* Code to implement Printing Dialogs. Described in rather complete
* fashion in Technical Note #95.
*/
/*
* This file is part of the DMP-110 printer driver for the Macintosh
* series of computers.
*/
/*
* Earle R. Horton.
* Wednesday, November 30, 1988
* All rights reserved.
*/
#include <Windows.h>
#include <Events.h>
#include <Dialogs.h>
#include <Controls.h>
#include <Lists.h>
#include <Fonts.h>
#include <Memory.h>
#include <Resources.h>
#include <ToolUtils.h>
#include <Packages.h>
#include <Menus.h>
#include "dmp-110.h"
#include "compat.h"
/*
* The Pascal Interface to MPW C 2.0.2 does not fully include the List Manager.
*/
#ifdef macintosh
pascal void LGetCell(Ptr,short *,Cell,ListHandle);
pascal void LSetCell(Ptr,short,Cell,ListHandle);
pascal void LSetSelect(Boolean,Cell,ListHandle);
#endif
#ifndef iDevDaisy
#define bDevDaisy 2
#define iDevDaisy (bDevDaisy << 8)
#endif
#define STYLEDIALOG (0xE000)
#define JOBDIALOG (0xE001)
#define XTRA 24 /* Six extra longs for our use. */
#define NORMALPRINT 0
#define DLGSIZE ((long)(sizeof(TPrDlg) + XTRA))
#define extra(tp,i) (* ((long *)((char *)(tp) + sizeof(TPrDlg)) + (i)))
#define TPSIZE ((long)(sizeof(TPrint)))
/* Items we handle in the job and style dialogs. */
#define CANCELITEM 2
#define STYLETITLE 4
#define STYLELIST 5
#define ALLBUTTON 5
#define RANGEBUTTON 6
#define FROMNUM 7
#define TONUM 9
#define COPIES 11
#define FANBUTTON 13
#define SHEETBUTTON 14
#ifdef MPU68000 /* Aztec does not yet do prototypes. */
pascal void CallItemProc();
pascal TPPrDlg CallDlgInit();
#else
pascal void CallItemProc(tp,itemhit,RealAddr) /* Glue. */
TPPrDlg tp;
short itemhit;
ProcPtr RealAddr;
extern;
pascal TPPrDlg CallDlgInit(hPrint,RealAddr) /* Glue. */
THPrint hPrint;
ProcPtr RealAddr;
extern;
#endif
/*
* Validate/update a print record.
*/
pascal Boolean MyPrValidate(hPrint)
THPrint hPrint;
{
THPrint thedefault;
if(Valid(hPrint)) return FALSE;
else{
thedefault = (THPrint)(GetResource('PREC',NORMALPRINT));
LoadResource(thedefault);
**hPrint = **thedefault;
return TRUE;
}
}
/*
* Printing dialog supervisor function.
* Reference: Macintosh Technical Note
* 95.
*/
pascal Boolean MyPrDlgMain(hPrint,pDlgInit)
THPrint hPrint;
ProcPtr pDlgInit;
{
TPPrDlg tp;
WindowPtr tempport;
short donetype,itemhit;
Handle doneitem;
Rect donebox;
ProcPtr itemproc;
tp = CallDlgInit(hPrint,pDlgInit);
itemproc = tp->pItemProc;
tp->fDone = FALSE;
tp->fDoIt = FALSE;
GetPort(&tempport);
SetPort(tp);
ShowWindow(tp);
GetDItem(tp,DONEITEM,&donetype,&doneitem,&donebox);
PenSize(3,3);
InsetRect(&donebox,-4,-4);
FrameRoundRect(&donebox,16,16);
PenSize(1,1);
while(!(tp->fDone)){
ModalDialog(tp->pFltrProc,&itemhit);
CallItemProc(tp,itemhit,itemproc);
}
SetPort(tempport);
CloseDialog(tp);
DisposPtr(tp);
if(tp->fDoIt) (void)MyPrValidate(hPrint);
return(tp->fDoIt);
}
/*
* Default item filter for print dialogs.
*/
pascal Boolean MyFilter(tp,theEvent,itemhit)
TPPrDlg tp;
EventRecord *theEvent;
short *itemhit;
{
char c;
if(theEvent->what == keyDown){
c = (theEvent->message & charCodeMask);
if( (c == 13) || (c == 3)){ /* Return or Enter. */
*itemhit = 1;
return TRUE;
}
}
return FALSE;
}
/*
* Style Dialog Filter. Give it to the List Manager if it is
* in the list of 'PREC's. Signal done if a double-click in a
* cell. Otherwise, handle via the normal filter.
*/
pascal Boolean MyStlFilter(tp,theEvent,itemhit)
TPPrDlg tp;
EventRecord *theEvent;
short *itemhit;
{
if(*itemhit == STYLELIST){
GlobalToLocal(&theEvent->where);
(void)LClick(theEvent->where,theEvent->modifiers,(ListHandle)extra(tp,0));
LocalToGlobal(&theEvent->where);
return FALSE;
}else{
return MyFilter(tp,theEvent,itemhit);
}
}
/*
* This function fills a print record with defaults. The default values
* are stored in the Printer resource file, in PREC 0. This is easy.
*/
pascal void MyPrintDefault(hPrint)
THPrint hPrint;
{
THPrint thedefault;
thedefault = (THPrint)(GetResource('PREC',NORMALPRINT));
LoadResource(thedefault);
**hPrint = **thedefault; /* What the hey. */
}
/*
* The next routine handles the style dialog. Two possibilities exist.
* If the cancel button is hit, then we signal quit. The print record
* is not changed.
* If the "OK" button is hit, then we have to fill in the new style in the
* user print record.
*/
pascal void HandleStyleItems(tp,itemhit)
TPPrDlg tp;
short itemhit;
{
short thenum,type;
Handle item;
Rect box,bigbox;
MenuHandle PRECMenu;
long restype;
short resid;
short nitems,i;
THPrint rPrint;
char thestring[256];
Point theCell;
switch(itemhit){
case DONEITEM:
SetPt(&theCell,0,0);
LGetSelect(0xFFFF,&theCell,(ListHandle)extra(tp,0));
i = 255;
LGetCell(&thestring[1],&i,theCell,(ListHandle)extra(tp,0));
thestring[0] = i;
rPrint = (THPrint)GetNamedResource('PREC',thestring);
if(rPrint == nil){
rPrint = (THPrint)GetResource('PREC',0);
}
LoadResource(rPrint);
(*(tp->hPrintUsr))->prInfo = (*rPrint)->prInfo;
(*(tp->hPrintUsr))->prInfoPT = (*rPrint)->prInfoPT;
(*(tp->hPrintUsr))->rPaper = (*rPrint)->rPaper;
(*(tp->hPrintUsr))->prStl = (*rPrint)->prStl;
(*(tp->hPrintUsr))->prXInfo = (*rPrint)->prXInfo;
(*(tp->hPrintUsr))->printX[0] = (*rPrint)->printX[0];
LDispose((ListHandle)extra(tp,0));
tp->fDone = TRUE;
tp->fDoIt = TRUE;
break;
case CANCELITEM:
LDispose((ListHandle)extra(tp,0));
tp->fDone = TRUE;
tp->fDoIt = FALSE;
break;
default:
break;
}
}
/*
* Symbolic constants used to make LNew() more readable.
*/
#define Drawn 0xFFFF
#define noGrow 0x0000
#define noHScroll 0x0000
#define vScroll 0xFFFF
#include <strings.h>
/*
* User item for putting up a list of available Print Records.
*/
pascal void PRECuserItem(tp,theitem)
TPPrDlg tp;
short theitem;
{
short type,i,j,nitems,id;
Handle item;
Rect listbox,dataBounds;
Point cellSize,theCell;
char thestring[256];
THPrint rPrint;
long restype;
ListHandle PRECList;
/*
* First time called, create the list.
*/
if(extra(tp,0) == nil){
GetDItem(tp,theitem,&type,&item,&listbox);
listbox.right -=15;
SetRect(&dataBounds,0,0,1,0);
SetPt(&cellSize,0,0);
PRECList = LNew(&listbox,&dataBounds,cellSize,0,(WindowPtr)tp,
Drawn,noGrow,noHScroll,vScroll);
(*PRECList)->selFlags = lDoHAutoscroll + lOnlyOne;
extra(tp,0) = (long)PRECList;
/*
* Read in the resources, put the names in the list.
*/
nitems = CountResources('PREC');
(void)LAddRow(nitems,0,PRECList);
for(i=0,j=0;i++<nitems;){
rPrint = (THPrint)GetIndResource('PREC',i);
GetResInfo(rPrint,&id,&restype,thestring);
SetPt(&theCell,0,j++);
LSetCell(&thestring[1],(short)thestring[0],theCell,PRECList);
if(((*tp->hPrintUsr))->printX[0] == id){
LSetSelect(0xFFFF,theCell,PRECList);
LAutoScroll(PRECList);
}
}
}
/*
* After the first time, just frame the item's Rect, and call LUpdate()
* to draw the list.
*/
GetDItem(tp,theitem,&type,&item,&listbox);
InsetRect(&listbox,-1,-1);
FrameRect(&listbox);
LUpdate(tp->Dlg.window.port.visRgn,(ListHandle)extra(tp,0));
}
/*
* The style dialog initializer. Get the dialog from the resource
* file, calculate the Rect for the Print Record list.
*/
pascal TPPrDlg MyPrStlInit(hPrint)
THPrint hPrint;
{
TPPrDlg tp;
short type;
Handle item;
Rect box,listbox;
tp = (TPPrDlg)NewPtr(DLGSIZE);
(GetNewDialog(STYLEDIALOG,tp,(WindowPtr)-1));
GetDItem(tp,STYLETITLE,&type,&item,&box);
listbox.left = box.right+20;
listbox.top = tp->Dlg.window.port.portRect.top+10;
listbox.bottom = tp->Dlg.window.port.portRect.bottom-10;
listbox.right = listbox.left + 200;
GetDItem(tp,STYLELIST,&type,&item,&box);
SetDItem(tp,STYLELIST,type,PRECuserItem,&listbox);
extra(tp,0) = nil;
tp->pFltrProc = (ProcPtr)MyStlFilter;
tp->pItemProc = (ProcPtr)HandleStyleItems;
tp->hPrintUsr = hPrint;
return(tp);
}
pascal Boolean MyPrStlDialog(hPrint) /* Conduct printer style dialog. */
THPrint hPrint;
{
return(MyPrDlgMain(hPrint,MyPrStlInit));
}
/*
* Record user choice of paper feed, page numbers, and
* number of copies.
*/
pascal void HandleJobItems(tp,itemhit)
TPPrDlg tp;
short itemhit;
{
short thenum;
long thelong;
Handle numitem;
Rect numbox;
char title[256];
switch(itemhit){
case DONEITEM:
tp->fDone = TRUE;
tp->fDoIt = TRUE;
if(buttonset(tp,ALLBUTTON)){
(*(tp->hPrintUsr))->prJob.iFstPage = iPrPgFst;
(*(tp->hPrintUsr))->prJob.iLstPage = iPrPgMax;
}else{
GetDItem(tp,FROMNUM,&thenum,&numitem,&numbox);
GetIText(numitem,&title[0]);
StringToNum(&title[0],&thelong);
(*(tp->hPrintUsr))->prJob.iFstPage = thelong;
GetDItem(tp,TONUM,&thenum,&numitem,&numbox);
GetIText(numitem,&title[0]);
StringToNum(&title[0],&thelong);
(*(tp->hPrintUsr))->prJob.iLstPage = thelong;
}
GetDItem(tp,COPIES,&thenum,&numitem,&numbox);
GetIText(numitem,&title[0]);
StringToNum(&title[0],&thelong);
(*(tp->hPrintUsr))->prJob.iCopies = (short)thelong;
if(buttonset(tp,SHEETBUTTON)){
(*(tp->hPrintUsr))->prStl.feed = feedCut;
}
else (*(tp->hPrintUsr))->prStl.feed = feedFanfold;
break;
case CANCELITEM:
tp->fDone = TRUE;
break;
case SHEETBUTTON:
pushradiobutton(tp,SHEETBUTTON,FANBUTTON,SHEETBUTTON);
(*(tp->hPrintUsr))->prStl.feed = feedCut;
break;
case FANBUTTON:
pushradiobutton(tp,FANBUTTON,FANBUTTON,SHEETBUTTON);
(*(tp->hPrintUsr))->prStl.feed = feedFanfold;
break;
case ALLBUTTON:
pushradiobutton(tp,ALLBUTTON,ALLBUTTON,RANGEBUTTON);
break;
case RANGEBUTTON:
pushradiobutton(tp,RANGEBUTTON,ALLBUTTON,RANGEBUTTON);
break;
default:
break;
}
}
/*
* The job dialog initializer. Make sure all the buttons
* come up reflecting the Print Record contents.
*/
pascal TPPrDlg MyPrJobInit(hPrint)
THPrint hPrint;
{
TPPrDlg tp;
short thenum;
Handle theitem;
Rect thebox;
char title[255];
tp = (TPPrDlg)NewPtr(DLGSIZE);
(GetNewDialog(JOBDIALOG,tp,(WindowPtr)-1));
pushradiobutton(tp,ALLBUTTON,ALLBUTTON,RANGEBUTTON);
if( (*hPrint)->prStl.feed == feedCut)
pushradiobutton(tp,SHEETBUTTON,FANBUTTON,SHEETBUTTON);
else
pushradiobutton(tp,FANBUTTON,FANBUTTON,SHEETBUTTON);
GetDItem(tp,FROMNUM,&thenum,&theitem,&thebox);
thenum = (*hPrint)->prJob.iFstPage;
NumToString((long)thenum,title);
SetIText(theitem,title);
GetDItem(tp,TONUM,&thenum,&theitem,&thebox);
thenum = (*hPrint)->prJob.iLstPage;
NumToString((long)thenum,title);
SetIText(theitem,title);
GetDItem(tp,COPIES,&thenum,&theitem,&thebox);
thenum = ((*hPrint)->prJob.iCopies /*= 1*/);
NumToString((long)thenum,title);
SetIText(theitem,title);
tp->pFltrProc = (ProcPtr)MyFilter;
tp->pItemProc = (ProcPtr)HandleJobItems;
tp->hPrintUsr = hPrint;
return(tp);
}
pascal Boolean MyPrJobDialog(hPrint) /* Conduct printer job dialog. */
THPrint hPrint;
{
return(MyPrDlgMain(hPrint,MyPrJobInit));
}
/*
* Copy a job subrecord. Update the destination record's printer information,
* band information, and paper rectangle, based on information in the job
* subrecord.
*/
pascal void MyPrJobMerge(hPrintSrc,hPrintDst)
THPrint hPrintSrc,hPrintDst;
{
(*hPrintDst)->prInfo.iDev = (*hPrintSrc)->prInfo.iDev;
(*hPrintDst)->prJob = (*hPrintSrc)->prJob;
(*hPrintDst)->prXInfo = (*hPrintSrc)->prXInfo;
(*hPrintDst)->rPaper = (*hPrintSrc)->rPaper;
(*hPrintDst)->prInfo = (*hPrintSrc)->prInfo;
(*hPrintDst)->prInfoPT = (*hPrintSrc)->prInfoPT;
}
/*
* Handy test for radio button down.
*/
int buttonset(d,num)
DialogPtr d;
short num;
{
short type;
Handle item;
Rect box;
GetDItem(d,num,&type,&item,&box);
if(GetCtlValue(item) == 1){
return true;
}else{
return false;
}
}
pushradiobutton(thedialog,itemhit,first,last) /* push a radio Button */
DialogPtr thedialog; /* set itemhit, unset */
int itemhit,first,last; /* all others in range */
{
int itemtype,i;
Handle itemhandle; /* Does check boxes, too. */
Rect itemrect;
if(first ==0) return;
for(i=first-1;last-i++;){
GetDItem(thedialog,i,&itemtype,&itemhandle,&itemrect);
if(i == itemhit) SetCtlValue(itemhandle,1);
else SetCtlValue(itemhandle,0);
}
}
/*
* This function answers the question: Can we possibly use this print
* record? Try to be somewhat liberal here. Don't allow a Print
* Record which will require a larger buffer than our printing
* routines can handle.
*/
int Valid(hPrint)
THPrint hPrint;
{
if (((*hPrint)->iPrVersion != VERSION)
|| ((*hPrint)->prInfo.iDev != 0)
|| ((*hPrint)->prJob.bJDocLoop != bDraftLoop))
return FALSE;
if(
(*hPrint)->prXInfo.iBandV != 64 ||
(*hPrint)->prXInfo.iBandH != 959 ||
(*hPrint)->prXInfo.iRowBytes != 120
)
return FALSE;
return TRUE;
}